import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Scanner;

import photoPrint.SystemClass;
import photoPrint.TADAlbum;
import photoPrint.TADPhoto;
import photoPrint.TADPrinter;
import photoPrint.TADSystem;

import dataStructures.Queue;

/**
 * 
 */

/**
 * @author filiperosa
 *
 */
public class Main {
	
	private static final String PHOTOSUCCESS = "Insercao de fotografia com sucesso.";
	private static final String PHOTOERROR = "Existencia de fotografia referida.";
	private static final String ADDALBUM = "Insercao de album com sucesso.";
	private static final String ADDALBUMERROR = "Existencia de album referido.";
	private static final String ADDPHOTOTOALBUM = "Adicao de fotografia a album.";
	private static final String ADDPHOTOTOALBUM1 = "Inexistencia de fotografia referida.";
	private static final String ADDPHOTOTOALBUM2 = "Album referido invalido.";
	private static final String ADDPHOTOTOALBUM3 = "Impossibilidade de realizar impressao.";
	private static final String ADDPRINTER = "Insercao de impressora com sucesso.";
	private static final String ADDPRINTER1 = "Existencia de impressora referida.";
	private static final String ADDPRINTER2 = "Valor de manutencao nao inferior a maximo de impressoes.";
	private static final String PRINTERREMOVED = "Remocao de impressora com sucesso.";
	private static final String PRINTERNOTREMOVED = "Inexistencia de impressora referida.";
	private static final String ALBUMADDEDTOPRINTER = "Adicao de album a impressora com sucesso.";
	private static final String ADDALBUMTOPRINTER1 = "Album vazio.";
	private static final String ADDALBUMTOPRINTER2 = "Necessidade de manutencao antes de adicao do album.";
	private static final String ADDALBUMTOPRINTER3 = "Impossibilidade de realizar impressao.";
	private static final String ADDALBUMTOPRINTER4 = "Inexistencia de album referido.";
	private static final String ADDALBUMTOPRINTER5 = "Inexistencia de impressora referida.";
	private static final String EMPTYSTACK = "Fila de espera vazia.";
	private static final String NOPRINTER = "Inexistencia de impressora referida.";
	private static final String MAINTENANCE = "Manutencao executada.";
	private static final String MAINTENANCEERROR = "Inexistencia de impressoras a necessitar de manutencao.";
	private static final String NOPRINTERS = "Inexistencia de impressoras.";



	
	
	public enum IOCommands {

		INSERT_PHOTO("IF"), INSERT_ALBUM("IA"), ADD_PHOTO_TO_ALBUM("AF"), ADD_PRINTER("II"), 
		REMOVE_PRINTER("RI"), ADD_ALBUM_TO_PRINTER("AP"), PRINT("EI"), MAINTENANCE("EM"), 
		LIST_PRINTERS("LI"); 
		

		private String name;
		IOCommands (String name) { this.name = name; }
		public String toString() { return this.name; }    

	}; 
	
	private static boolean isCommand(String str, IOCommands cmd) {
		return str.equalsIgnoreCase(cmd.toString());
	}
	
	/**
	 * @param args
	 * @throws IOException 
	 * @throws ClassNotFoundException 
	 */
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		Scanner in = new Scanner(System.in);
		TADSystem system;
		system = new SystemClass();
		menu(system, in);
	}
	
	private static void menu(TADSystem system, Scanner in) throws IOException, ClassNotFoundException{
		system = load();
		while ( in.hasNext()) {
			String command = in.nextLine();
			String input[]= command.split(" ");
			String cmd1 = input[0].trim();
			if ( isCommand(cmd1, IOCommands.INSERT_PHOTO) ) {
				addPhoto(system,in,input);
			}
			else if ( isCommand(cmd1, IOCommands.INSERT_ALBUM) ) {
				addAlbum(system, input);  
			} 
			else if ( isCommand(cmd1, IOCommands.ADD_PHOTO_TO_ALBUM) ) {
				addPhotoToAlbum(system, in, input);  
			} 
			else if ( isCommand(cmd1, IOCommands.ADD_PRINTER) ) {
				addPrinter(system, in, input);  
			} 
			else if ( isCommand(cmd1, IOCommands.REMOVE_PRINTER) ) {
				removePrinter(system, input);  
			} 
			else if ( isCommand(cmd1, IOCommands.ADD_ALBUM_TO_PRINTER) ) {
				addAlbumToPrinter(system, input);  
			}
			else if ( isCommand(cmd1, IOCommands.PRINT) ) {
				print(system, input);
			}
			else if ( isCommand(cmd1, IOCommands.MAINTENANCE) ) {
				maintenance(system);  
			}
			else if ( isCommand(cmd1, IOCommands.LIST_PRINTERS) ) {
				listPrinters(system);  
			}

		}
		store(system);
	}

	private static void listPrinters(TADSystem system2) {
		TADPrinter printer = system2.printer();
		if (printer!=null){
			if (printer.needsMaintenance()){
				System.out.println("- "+printer.getName()+" necessita de manutencao.");
			}
			else System.out.println("- "+printer.getName()+".");
		}
		else System.out.println(NOPRINTERS);
		System.out.println();
				
	}

	private static void maintenance(TADSystem system2) {
		if (system2.maintenance())
			System.out.println(MAINTENANCE);
		else System.out.println(MAINTENANCEERROR);
		System.out.println();
	}

	private static void print(TADSystem system, String[] input){
		String name="";
		int i =1;
		while(i<input.length){
			if(i==input.length-1){
				name= name + input[i].toLowerCase().trim();
				i++;
			}
			else{
				name= name + input[i].toLowerCase().trim() + " ";
				i++;
			}
		}
		TADPrinter printer = system.printer();
		if (printer!=null) {
			if (printer.getName().equalsIgnoreCase(name)) {
				Queue<TADAlbum> stack = system.print(name);
				if (!stack.isEmpty()) {
					System.out.println(printer.getName().toLowerCase() + " "
							+ printer.getLocation()+".");
					TADAlbum album = null;
					TADPhoto photo = null;
					Queue<TADPhoto> albumPhotos = null;
					while (!stack.isEmpty()) {
						album = stack.dequeue();
						albumPhotos = album.getPhotos();
						while (!albumPhotos.isEmpty()) {
							photo = albumPhotos.dequeue();
							System.out.println(photo.getName() + " impresso.");
						}
					}
				} else
					System.out.println(EMPTYSTACK);
			}
			else System.out.println(NOPRINTER);;
		}
		else System.out.println(NOPRINTER);
		System.out.println();
	}

	private static void addAlbumToPrinter(TADSystem system2, String[] input) {
		String albumCode = input[1].trim();
		String name="";
		int i =2;
		while(i<input.length){
			if(i==input.length-1){
				name= name + input[i].toLowerCase().trim();
				i++;
			}
			else{
				name= name + input[i].toLowerCase().trim() + " ";
				i++;
			}
		}
		name.toLowerCase();
		int result = system2.addAlbumToPrinter(albumCode, name);
		if (result==0){
			System.out.println(ALBUMADDEDTOPRINTER);
		}
		else if (result==4){
			System.out.println(ADDALBUMTOPRINTER4);
		}
		else if (result==5){
			System.out.println(ADDALBUMTOPRINTER5);
		}	
		else if (result==2){
			System.out.println(ADDALBUMTOPRINTER2);
		}
		else if (result==3){
			System.out.println(ADDALBUMTOPRINTER3);
		}
		else if (result==1){
			System.out.println(ADDALBUMTOPRINTER1);
		}
		System.out.println();
	}

	private static void removePrinter(TADSystem system2, String[] input) {
		String name="";
		int i =1;
		while(i<input.length){
			if(i==input.length-1){
				name= name + input[i].toLowerCase().trim();
				i++;
			}
			else{
				name= name + input[i].toLowerCase().trim() + " ";
				i++;
			}
		}
		name.toLowerCase();
		boolean result = system2.removePrinter(name);
		if (result){
			System.out.println(PRINTERREMOVED);
		}
		else System.out.println(PRINTERNOTREMOVED);
		System.out.println();
	}

	private static void addPrinter(TADSystem system2, Scanner in, String[] input) {
		String name="";
		int i =1;
		while(i<input.length){
			if(i==input.length-1){
				name= name + input[i].toLowerCase().trim();
				i++;
			}
			else{
				name= name + input[i].toLowerCase().trim() + " ";
				i++;
			}
		}
		String location = in.nextLine().trim().toLowerCase();
		int maxWidth = in.nextInt();
		int maxHeight = in.nextInt();
		int maxPrints = in.nextInt();
		int maintenanceValue = in.nextInt();
		int result = system2.addPrinter(name, location, maxWidth, maxHeight, maxPrints, maintenanceValue);
		if (result==0){
			System.out.println(ADDPRINTER);
		}
		else if (result==2){
			System.out.println(ADDPRINTER2);
		}
		else if (result==1){
			System.out.println(ADDPRINTER1);
		}
		System.out.println();
	}

	private static void addPhotoToAlbum(TADSystem system, Scanner in, String[] input) {
		String photoCode = input[1].trim();
		String albumCode = input[2].trim();
		int printWidth = in.nextInt();
		int printHeight = in.nextInt();
		int result = system.addPhotoToAlbum(photoCode, albumCode, printWidth, printHeight);
		if (result == 0){
			System.out.println(ADDPHOTOTOALBUM);
		}
		else if(result == 1){
			System.out.println(ADDPHOTOTOALBUM1);
		}
		else if(result == 2){
			System.out.println(ADDPHOTOTOALBUM2);
		}
		else if(result == 3){
			System.out.println(ADDPHOTOTOALBUM3);
		}
		System.out.println();
	}

	private static void addAlbum(TADSystem system2, String[] input) {
		String  code = input[1].trim();
		boolean result = system2.addAlbum(code);
		if (result){
			 System.out.println(ADDALBUM);
		 }
		else System.out.println(ADDALBUMERROR);
		System.out.println();

	}

	private static void addPhoto(TADSystem system2, Scanner in, String[] input) {
		String code = input[1].trim();
		String name="";
		int i =2;
		while(i<input.length){
			if(i==input.length-1){
				name= name + input[i].toLowerCase().trim();
				i++;
			}
			else{
				name= name + input[i].toLowerCase().trim() + " ";
				i++;
			}
		}
		name.toLowerCase();
		int width = in.nextInt();
		int height = in.nextInt();
		boolean result = system2.addPhoto(code, name, width, height);
		if (result){
			System.out.println(PHOTOSUCCESS);
			System.out.println();
		}
		else{
			System.out.println(PHOTOERROR);
			System.out.println();}
	}
		
	public static void store(TADSystem system){ 
		try{
			ObjectOutputStream file = new ObjectOutputStream( new FileOutputStream("file") );
			file.writeObject(system);
			file.flush();
			file.close();
		}
		catch ( IOException e ) {
			e.printStackTrace();
		}
		}
    
    public static TADSystem load(){ 
    	TADSystem system = null;
    	try{
    		ObjectInputStream file = new ObjectInputStream( new FileInputStream("file") );
    		system = (TADSystem) file.readObject();
    		file.close();
    	}
    	catch ( IOException e ) {
    		system = new SystemClass();
    	}
    	catch ( ClassNotFoundException e ){
    		e.printStackTrace();
            System.exit(0);
    	} 
    	return system;
    }
}

